/**
 * <pre>
 * Title: 		MessageServiceImpl.java
 * Project: 	MSBS
 * Author:		pengfangliang
 * Create:	 	2012-7-6 上午09:57:51
 * Copyright: 	Copyright (c) 2012
 * Company:		Shenzhen Helper
 * <pre>
 */
package com.hengpeng.itfin.service.impl;

import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.hengpeng.common.persist.entity.AbstractEntity.BoolValue;
import com.hengpeng.common.persist.query.DynamicQuery;
import com.hengpeng.common.persist.query.Projections;
import com.hengpeng.common.persist.query.Restrictions;
import com.hengpeng.common.persist.query.constants.QueryConstants.QueryType;
import com.hengpeng.common.util.DateTimeUtil;
import com.hengpeng.itfin.domain.partner.chinapnr.ChinapnrProcessorImpl;
import com.hengpeng.itfin.service.MessageService;
import com.hengpeng.itfin.tools.PoolServer;
import com.hengpeng.itfinbase.en.MessagetemplatesEnum;
import com.hengpeng.itfinbase.message.ResponseMessage;
import com.hengpeng.itfinbase.message.userInfo.MessageRequest;
import com.hengpeng.itfinbase.persist.Message;
import com.hengpeng.itfinbase.persist.Message.MessageType;
import com.hengpeng.itfinbase.persist.MessageReceiver;
import com.hengpeng.itfinbase.persist.MessageTemplates;
import com.hengpeng.itfinbase.persist.MessageTemplates.BusiType;
import com.hengpeng.itfinbase.persist.UserInfo;

/**
 * <pre>
 * 站内消息服务层接口实现
 * </pre>
 * 
 * @author pengfangliang
 * @version 1.0, 2012-7-6
 */
@Service
@Lazy
public class MessageServiceImpl extends BaseServiceImpl implements MessageService {
    private static final Log logger = LogFactory.getLog(ChinapnrProcessorImpl.class);

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public ResponseMessage batchDeleteMessage(MessageRequest request) {
        DynamicQuery query = new DynamicQuery(MessageReceiver.class);
        query.add(Restrictions.inArray("id", request.getIds().toArray(new Object[request.getIds().size()])));
        List<MessageReceiver> list = serviceFactory.getDaoFactory().getCommonDao().findEntityByDynamicQuery(query,
                MessageReceiver.class);
        for (MessageReceiver messageReceiver : list) {
            messageReceiver.setIsDelete(BoolValue.YES);
        }
        serviceFactory.getDaoFactory().getCommonDao().updateAllEntity(list);
        return new ResponseMessage();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public ResponseMessage batchMarkMessageReaded(MessageRequest request) {
        DynamicQuery query = new DynamicQuery(MessageReceiver.class);
        query.add(Restrictions.inArray("id", request.getIds().toArray(new Object[request.getIds().size()])));
        List<MessageReceiver> list = serviceFactory.getDaoFactory().getCommonDao().findEntityByDynamicQuery(query,
                MessageReceiver.class);
        List<Message> messageList = new ArrayList<Message>();
        for (MessageReceiver messageReceiver : list) {
            messageReceiver.setIsRead(BoolValue.YES);
            Message message = serviceFactory.getDaoFactory().getCommonDao().getEntity(Message.class,
                    messageReceiver.getMessageId());
            message.setReadTotal(message.getReadRate() + 1);
            messageList.add(message);
        }
        if (messageList.size() > 0 && list.size() > 0) {
            serviceFactory.getDaoFactory().getCommonDao().updateAllEntity(messageList);
            serviceFactory.getDaoFactory().getCommonDao().updateAllEntity(list);
        }
        return new ResponseMessage();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void sendMessge(UserInfo user) {
        DynamicQuery query = new DynamicQuery(Message.class);
        query.eq("isPublish", BoolValue.YES);
        query.eq("type", MessageType.IMPORTANT);// 非系统发送用户(系统发送的是时时发送、修改密码成、提现成功)
        query.add(Restrictions.or(Restrictions.isNull("sendTime"), Restrictions.ge("sendTime", new Date())));// 定时发送情况
        List<Message> messageList = serviceFactory.getDaoFactory().getCommonDao().findEntityByDynamicQuery(query,
                Message.class);
        for (Message message : messageList) {
            // 注册时间在站内信发布时间之前的用户才发送
            if (user.getRegisterTime() != null && message.getPublishDate() != null
                    && user.getRegisterTime().getTime() <= message.getPublishDate().getTime()) {
                switch (message.getSendType()) {
                case ALLMEMBER:
                    sendToMember(user.getUserName(), message);
                    break;
                case SINGLEMEMBER:
                    sendToSingleMember(user.getUserName(), message);
                    break;
                default:
                    break;
                }
            }
        }
    }

    private void sendToSingleMember(String userName, Message message) {
        String[] users = message.getUserName().split(";");
        for (String user : users) {
            if (user.equals(userName)) {
                sendToMember(userName, message);
                break;
            }
        }
    }

    private void sendToMember(String userName, Message message) {
        if (isUnsendMessage(userName, message.getId())) {
            serviceFactory.getDaoFactory().getCommonDao().saveEntity(fillMessageReceiver(userName, message.getId()));
        }
    }

    private Boolean isUnsendMessage(String userName, Long messasgeId) {
        DynamicQuery query = new DynamicQuery(MessageReceiver.class);
        query.eq("messageId", messasgeId);
        query.eq("userName", userName);
        query.addProjection(Projections.count());
        int count = serviceFactory.getDaoFactory().getCommonDao().countByDynamicQuery(query, MessageReceiver.class);
        if (count == 0) {
            return true;
        } else {
            return false;
        }
    }

    private MessageReceiver fillMessageReceiver(String userName, Long messageId) {
        MessageReceiver mr = new MessageReceiver();
        mr.setUserName(userName);
        mr.setMessageId(messageId);
        mr.setIsRead(BoolValue.NO);
        mr.setIsDelete(BoolValue.NO);
        return mr;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void sendSystemMessage(String userName, String title, String content) {
        Message message = new Message();
        message.setUserName(userName);
        message.setContent(content);
        message.setCreatDate(new Date());
        message.setIsPublish(BoolValue.YES);
        message.setPublishDate(new Date());
        message.setReadRate(0);
        message.setReadTotal(0);
        message.setReceiverTotal(1);
        message.setSender(MessageType.COMMON.toString());
        message.setSummary(null);
        message.setTitle(title);
        message.setType(MessageType.COMMON);// 系统发送
        message = serviceFactory.getDaoFactory().getCommonDao().saveEntity(message);
        MessageReceiver mr = new MessageReceiver();
        mr.setUserName(userName);
        mr.setIsRead(BoolValue.NO);
        mr.setMessageId(message.getId());
        mr.setIsDelete(BoolValue.NO);
        serviceFactory.getDaoFactory().getCommonDao().saveEntity(mr);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void sendDrawMessage(String userName, String accountNo, Date lastTime, Integer drawMoney) {
        NumberFormat format = NumberFormat.getCurrencyInstance(Locale.CHINA);
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        UserInfo member = serviceFactory.getDaoFactory().getUserInfoDao().getUserByUserName(userName);
        String head = member.getUserName() + ",您好!\n";
        String title = "成功提现" + format.format(drawMoney * 0.01) + " 元";
        String body = "&nbsp;&nbsp;您于" + dateFormat.format(lastTime) + title + "到您的绑定提现银行卡号" + accountNo + "账户中。";
        sendSystemMessage(userName, title, head + body);
    }

    @Override
    public String sendSystemMessageByType(String userName, String busiType, Map<String, ?> map) {
        MessageTemplates messageTemplates = this.getMessageTemplatesByType(busiType, 1);
        if (null == messageTemplates || StringUtils.isEmpty(messageTemplates.getContent())
                || StringUtils.isEmpty(userName)) {
            return null;
        }
        String messageTemplatesContent = messageTemplates.getContent();
        String content = messageTemplatesContent
                .replaceAll(MessagetemplatesEnum.DATE.getText(),
                        map.get("date") == null ? "" : DateTimeUtil.formatLongStr((Date) map.get("date")))
                .replaceAll(MessagetemplatesEnum.MONEY.getText(),
                        map.get("money") == null ? "" : map.get("money").toString())
                .replace(MessagetemplatesEnum.USERNAME.getText(),
                        map.get("userName") == null ? "" : map.get("userName").toString());
        this.sendMessage(userName, "", content);
        return content;
    }

    @Override
    public String sendSystemMessageByTypeWithUsrCustId(String usrCustId, String busiType, Map<String, ?> map) {
        if (StringUtils.isEmpty(usrCustId)) {
            return null;
        }

        DynamicQuery query = new DynamicQuery(UserInfo.class);
        query.eq("trustAccountId", usrCustId);
        query.setQueryType(QueryType.JDBC);
        UserInfo userInfo = serviceFactory.getDaoFactory().getCommonDao().getByDynamicQuery(query, UserInfo.class);
        if (null == userInfo) {
            return null;
        }

        String userName = userInfo.getUserName();
        return this.sendSystemMessageByType(userName, busiType, map);

    }

    @Override
    public void asynsendSystemMessageByTypeWithUsrCustId(final String usrCustId, final String busiType,
            final Map<String, ?> map) {
        try {
            PoolServer poolServer = new PoolServer(1);
            poolServer.executeTask(new Runnable() {
                @Override
                public void run() {
                    sendSystemMessageByTypeWithUsrCustId(usrCustId, busiType, map);
                }
            });
            poolServer.endServer();
        } catch (Exception e) {
            logger.error(usrCustId, e);
        }
    }
    
    @Override
    public void asynsendSystemMessageByTypeWithUserName(final String userName, final String busiType,
            final Map<String, ?> map) {
        try {
            PoolServer poolServer = new PoolServer(1);
            poolServer.executeTask(new Runnable() {
                @Override
                public void run() {
                    sendSystemMessageByType(userName, busiType, map);
                }
            });
            poolServer.endServer();
        } catch (Exception e) {
            logger.error(userName, e);
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void sendMessage(String userName, String title, String content) {
        Message message = new Message();
        message.setUserName(userName);
        message.setContent(content);
        message.setCreatDate(new Date());
        message.setIsPublish(BoolValue.YES);
        message.setPublishDate(new Date());
        message.setReadRate(0);
        message.setReadTotal(0);
        message.setReceiverTotal(1);
        message.setSender(MessageType.COMMON.toString());
        message.setSummary(null);
        message.setTitle(title);
        message.setType(MessageType.COMMON);// 系统发送
        message = serviceFactory.getPersistService().save(message);
    }

    private MessageTemplates getMessageTemplatesByType(String busiType, Integer status) {

        DynamicQuery query = new DynamicQuery(MessageTemplates.class);
        if (!StringUtils.isEmpty(busiType)) {
            BusiType b = BusiType.getBusiTypeByName(busiType);
            query.eq("busitype", b);
        }
        if (null != status) {
            query.eq("status", status);
        }
        query.setQueryType(QueryType.JDBC);
        return this.serviceFactory.getDaoFactory().getCommonDao().getByDynamicQuery(query, MessageTemplates.class);
    }
}
